package com.platform.common.authentication.stateless;

import com.alibaba.fastjson.JSONObject;
import com.platform.common.authentication.entity.properties.RequestProperties;
import com.platform.common.util.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.web.filter.AccessControlFilter;
import org.springframework.beans.factory.annotation.Autowired;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @description: 无状态认证拦截器
 * @author: WangYang
 * @date: 2017-09-28 14:34
 */
@Slf4j
public class StatelessAuthFilter extends AccessControlFilter {

    @Autowired
    private RequestProperties requestProperties;

    @Override
    protected boolean isAccessAllowed(ServletRequest request,
                                      ServletResponse response,
                                      Object mappedValue) throws Exception {
        return false;
    }

    @Override
    protected boolean onAccessDenied(ServletRequest request,
                                     ServletResponse response) throws Exception {
        HttpServletRequest req = (HttpServletRequest) request;
        String userName = requestProperties == null ? "account" : requestProperties.getUserName();
        String tokenName = requestProperties == null ? "token" : requestProperties.getTokenName();
        String account = req.getHeader(userName);
        String token = req.getHeader(tokenName);
        if (StringUtils.isEmpty(token) || StringUtils.isEmpty(account)) {
            onLoginFail(response);
            return false;
        }
        StatelessToken statelessToken = new StatelessToken(account, token);
        try {
            // 委托给Realm进行登录
            getSubject(request, response).login(statelessToken);
        } catch (Exception e) {
            log.error("权限拦截异常：", e);
            // 登录失败
            onLoginFail(response);
            return false;
        }
        return true;
    }

    /**
     * 登录失败时默认返回401状态码
     *
     * @param response
     * @throws IOException
     */
    private void onLoginFail(ServletResponse response) throws IOException {
        HttpServletResponse httpResponse = (HttpServletResponse) response;
        httpResponse.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
        JSONObject json = new JSONObject();
        json.put("msg", "unauthorized");
        response.getWriter().write(json.toString());
    }
}
